Loading the relevant libraries:

# for reading data and data carpentry
library(readr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(units)
## udunits database from /usr/share/udunits/udunits2.xml
library(purrr)

# for handling spatial data
library(sf)
## Linking to GEOS 3.14.1, GDAL 3.12.1, PROJ 9.7.0; sf_use_s2() is TRUE
library(tidygeocoder)
library(crsuggest)
## Using the EPSG Dataset v10.019, a product of the International Association of Oil & Gas Producers. 
## Please view the terms of use at https://epsg.org/terms-of-use.html.
# for mapping and visualization
library(leaflet)
library(RColorBrewer)

# for providing access to spatial data
library(osmdata)
## Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright

Exploring the relationship between alcohol outlets and crime

Are alcohol outlets crime attractors or crime generators?

Acquiring relevant data

Reading in crime data:

crimes <- read_csv("data/data/2019-06-greater-manchester-street.csv")
## Rows: 32058 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (9): Crime ID, Month, Reported by, Falls within, Location, LSOA code, LS...
## dbl (2): Longitude, Latitude
## lgl (1): Context
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(crimes)
## Rows: 32,058
## Columns: 12
## $ `Crime ID`              <chr> NA, "aa1cc4cb0c436f463635890bcb4ff2cba08f59925…
## $ Month                   <chr> "2019-06", "2019-06", "2019-06", "2019-06", "2…
## $ `Reported by`           <chr> "Greater Manchester Police", "Greater Manchest…
## $ `Falls within`          <chr> "Greater Manchester Police", "Greater Manchest…
## $ Longitude               <dbl> -2.464422, -2.441166, -2.444807, -2.444807, -2…
## $ Latitude                <dbl> 53.61250, 53.61604, 53.61151, 53.61151, 53.606…
## $ Location                <chr> "On or near Parking Area", "On or near Pitcomb…
## $ `LSOA code`             <chr> "E01004768", "E01004768", "E01004768", "E01004…
## $ `LSOA name`             <chr> "Bolton 001A", "Bolton 001A", "Bolton 001A", "…
## $ `Crime type`            <chr> "Anti-social behaviour", "Violence and sexual …
## $ `Last outcome category` <chr> NA, "Unable to prosecute suspect", "Unable to …
## $ Context                 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…

Cleaning the variable names using janitor::clean_names():

crimes <- clean_names(crimes)
glimpse(crimes)
## Rows: 32,058
## Columns: 12
## $ crime_id              <chr> NA, "aa1cc4cb0c436f463635890bcb4ff2cba08f599250b…
## $ month                 <chr> "2019-06", "2019-06", "2019-06", "2019-06", "201…
## $ reported_by           <chr> "Greater Manchester Police", "Greater Manchester…
## $ falls_within          <chr> "Greater Manchester Police", "Greater Manchester…
## $ longitude             <dbl> -2.464422, -2.441166, -2.444807, -2.444807, -2.4…
## $ latitude              <dbl> 53.61250, 53.61604, 53.61151, 53.61151, 53.60627…
## $ location              <chr> "On or near Parking Area", "On or near Pitcombe …
## $ lsoa_code             <chr> "E01004768", "E01004768", "E01004768", "E0100476…
## $ lsoa_name             <chr> "Bolton 001A", "Bolton 001A", "Bolton 001A", "Bo…
## $ crime_type            <chr> "Anti-social behaviour", "Violence and sexual of…
## $ last_outcome_category <chr> NA, "Unable to prosecute suspect", "Unable to pr…
## $ context               <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …

Reading in a geoJSON spatial file:

manchester_ward <- st_read("data/data/wards.geojson")
## Reading layer `wards' from data source 
##   `/home/norman/Documents/ThirdBrain/x1_Projects/RProjects/Notes-on-Crime-Mapping-and-Spatial-Data-Analysis-in-R/data/data/wards.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 215 features and 12 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 351664 ymin: 381168.6 xmax: 406087.5 ymax: 421039.8
## Projected CRS: OSGB36 / British National Grid
head(manchester_ward)
## Simple feature collection with 6 features and 12 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 351664 ymin: 394521.5 xmax: 369078.9 ymax: 407481
## Projected CRS: OSGB36 / British National Grid
##   objectid    wd16cd      wd16nm wd16nmw   lad16cd lad16nm  bng_e  bng_n
## 1      772 E05000851        Ince    <NA> E08000010   Wigan 359959 405278
## 2      773 E05000852  Leigh East    <NA> E08000010   Wigan 367298 400695
## 3      774 E05000853 Leigh South    <NA> E08000010   Wigan 366260 398660
## 4      775 E05000854  Leigh West    <NA> E08000010   Wigan 363428 400762
## 5      776 E05000855 Lowton East    <NA> E08000010   Wigan 362642 397699
## 6      777 E05000856      Orrell    <NA> E08000010   Wigan 353321 404083
##       long      lat st_areasha st_lengths                       geometry
## 1 -2.60570 53.54262    4780173   11442.63 POLYGON ((359198.5 403803.5...
## 2 -2.49447 53.50194    4972092   11056.20 POLYGON ((367700.6 401583.7...
## 3 -2.50990 53.48358    6521214   12377.97 POLYGON ((364490 397331.6, ...
## 4 -2.55282 53.50228    7315344   16159.92 POLYGON ((363107.9 399684.9...
## 5 -2.56431 53.47470   11185415   17990.73 POLYGON ((361792.3 394521.5...
## 6 -2.70568 53.53133    8884317   19650.85 POLYGON ((353418.8 407481, ...

Too much data! Filtering:

city_center <- manchester_ward |> 
  filter(wd16nm == "City Centre")

head(city_center)
## Simple feature collection with 1 feature and 12 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 382621 ymin: 397086.1 xmax: 385710.4 ymax: 399156.8
## Projected CRS: OSGB36 / British National Grid
##   objectid    wd16cd      wd16nm wd16nmw   lad16cd    lad16nm  bng_e  bng_n
## 1      618 E05000697 City Centre    <NA> E08000003 Manchester 383942 398119
##       long      lat st_areasha st_lengths                       geometry
## 1 -2.24342 53.47956    3102193   8569.712 POLYGON ((384111.6 399137.3...

Extracting the geometry data only using st_geometry():

city_center_geometry <- st_geometry(city_center)

# quickly plot the geometry object
plot(city_center_geometry)
Plot of city center ward geometry

Plot of city center ward geometry

Getting the bounding box for our region of interest, usingosmdata::getbb():

bb_sf <- osmdata::getbb(
  place_name = "greater manchester united kingdom",
  format_out = "sf_polygon"
)

head(bb_sf)
## Simple feature collection with 1 feature and 13 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -2.730521 ymin: 53.32731 xmax: -1.909622 ymax: 53.68572
## Geodetic CRS:  WGS 84
##    place_id
## 1 256958817
##                                                                 licence
## 1 Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright
##   osm_type osm_id        lat        lon    class           type place_rank
## 1 relation  88084 53.5065249 -2.3374401 boundary administrative         10
##   importance    addresstype               name
## 1  0.6538459 state_district Greater Manchester
##                                  display_name                       geometry
## 1 Greater Manchester, England, United Kingdom POLYGON ((-2.730521 53.5205...
# quickly plot the geometry object from `bb_sf`:
plot(st_geometry(bb_sf))
Plot of Greater Manchester boundary

Plot of Greater Manchester boundary

Querying OSM for bars (the drinking establishment) within the Greater Manchester Area using opq() (which stands for “overpass query”):

osm_bar_sf <- osmdata::opq(bbox = bb_sf) |>  # select bounding box
  add_osm_feature(key = "amenity", value = "bar") |>  # select features
  osmdata_sf() # specify class

class(osm_bar_sf)
## [1] "osmdata_sf" "osmdata"    "list"

Inspecting osm_bar_sf

head(osm_bar_sf)
## $bbox
## [1] "relation(id:88084)"
## 
## $overpass_call
## [1] "[out:xml][timeout:25];\n(relation(id:88084); map_to_area->.searchArea; );\n(\n  node [\"amenity\"=\"bar\"] (area.searchArea);\n  way [\"amenity\"=\"bar\"] (area.searchArea);\n  relation [\"amenity\"=\"bar\"] (area.searchArea);\n);\n(._;>;);\nout body;"
## 
## $meta
## $meta$timestamp
## [1] "[ Tue 6 Jan 2026 16:09:29 ]"
## 
## $meta$OSM_version
## [1] "0.6"
## 
## $meta$overpass_version
## [1] "Overpass API 0.7.61.8 b1080abd"
## 
## 
## $osm_points
## Simple feature collection with 819 features and 118 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -2.704108 ymin: 53.35707 xmax: -2.005355 ymax: 53.64882
## Geodetic CRS:  WGS 84
## First 10 features:
##              osm_id                     name access  addr:city addr:country
## 27024694   27024694        Didsbury Junction   <NA> Manchester           GB
## 30969134   30969134            The Grosvenor   <NA> Manchester         <NA>
## 30969136   30969136               Revolution   <NA> Manchester           GB
## 30969137   30969137            Joshua Brooks   <NA> Manchester         <NA>
## 268980212 268980212           Slug & Lettuce   <NA> Manchester         <NA>
## 293617257 293617257          Fifth Nightclub   <NA> Manchester           GB
## 324671296 324671296 Slug & Lettuce Deansgate   <NA> Manchester         <NA>
## 324696522 324696522                 Cloud 23   <NA>       <NA>         <NA>
## 331413286 331413286         Slug and Lettuce   <NA> Manchester         <NA>
## 334648390 334648390       Revolución de Cuba   <NA> Manchester           GB
##           addr:county addr:floor    addr:housename addr:housenumber addr:place
## 27024694         <NA>       <NA>              <NA>          844-846   Didsbury
## 30969134         <NA>       <NA>       The Footage             <NA>       <NA>
## 30969136         <NA>       <NA>              <NA>            88-94       <NA>
## 30969137         <NA>       <NA>              <NA>              106       <NA>
## 268980212        <NA>       <NA>              <NA>              651       <NA>
## 293617257        <NA>       <NA>              <NA>              121       <NA>
## 324671296        <NA>       <NA>              <NA>               62       <NA>
## 324696522        <NA>       <NA>              <NA>             <NA>       <NA>
## 331413286        <NA>       <NA>       Heron House            11-12       <NA>
## 334648390        <NA>       <NA> Central Buildings               11       <NA>
##           addr:postcode addr:state      addr:street addr:subdistrict
## 27024694        M20 2RN       <NA>    Wilmslow Road             <NA>
## 30969134         M1 7DZ       <NA> Grosvenor Street             <NA>
## 30969136         M1 5WH       <NA>    Oxford Street             <NA>
## 30969137         M1 6NG       <NA>  Princess Street             <NA>
## 268980212       M20 6QZ       <NA>    Wilmslow Road             <NA>
## 293617257        M1 7AG       <NA>  Princess Street             <NA>
## 324671296        M3 2EN       <NA>        Deansgate             <NA>
## 324696522          <NA>       <NA>             <NA>             <NA>
## 331413286        M2 5HD       <NA>    Albert Square             <NA>
## 334648390        M2 5QR       <NA>     Peter Street             <NA>
##           addr:suburb addr:town addr:unit air_conditioning alt_name amenity
## 27024694         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 30969134         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 30969136         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 30969137         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 268980212        <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 293617257        <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 324671296        <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 324696522        <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 331413286        <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 334648390        <NA>      <NA>      <NA>             <NA>     <NA>     bar
##           amenity_1  bar barrier branch              brand brand:wikidata
## 27024694       <NA> <NA>    <NA>   <NA>               <NA>           <NA>
## 30969134       <NA> <NA>    <NA>   <NA>               <NA>           <NA>
## 30969136       <NA> <NA>    <NA>   <NA>         Revolution      Q64024398
## 30969137       <NA> <NA>    <NA>   <NA>               <NA>           <NA>
## 268980212      <NA> <NA>    <NA>   <NA>   Slug and Lettuce       Q7542224
## 293617257      <NA> <NA>    <NA>   <NA>               <NA>           <NA>
## 324671296      <NA> <NA>    <NA>   <NA>   Slug and Lettuce       Q7542224
## 324696522      <NA> <NA>    <NA>   <NA>               <NA>           <NA>
## 331413286      <NA> <NA>    <NA>   <NA>   Slug and Lettuce       Q7542224
## 334648390      <NA> <NA>    <NA>   <NA> Revolución de Cuba      Q64024691
##           brand:wikipedia breakfast brewery building changing_table
## 27024694             <NA>      <NA>    <NA>     <NA>           <NA>
## 30969134             <NA>      <NA>    <NA>     <NA>           <NA>
## 30969136             <NA>      <NA>    <NA>     <NA>           <NA>
## 30969137             <NA>      <NA>    <NA>     <NA>           <NA>
## 268980212            <NA>      <NA>    <NA>     <NA>           <NA>
## 293617257            <NA>      <NA>    <NA>     <NA>           <NA>
## 324671296            <NA>      <NA>    <NA>     <NA>           <NA>
## 324696522            <NA>      <NA>    <NA>     <NA>           <NA>
## 331413286            <NA>      <NA>    <NA>     <NA>           <NA>
## 334648390            <NA>      <NA>    <NA>     <NA>           <NA>
##           changing_table:count changing_table:location check_date
## 27024694                  <NA>                    <NA>       <NA>
## 30969134                  <NA>                    <NA>       <NA>
## 30969136                  <NA>                    <NA> 2025-08-14
## 30969137                  <NA>                    <NA>       <NA>
## 268980212                 <NA>                    <NA>       <NA>
## 293617257                 <NA>                    <NA>       <NA>
## 324671296                 <NA>                    <NA>       <NA>
## 324696522                 <NA>                    <NA>       <NA>
## 331413286                 <NA>                    <NA>       <NA>
## 334648390                 <NA>                    <NA>       <NA>
##           check_date:opening_hours cocktails contact:email contact:facebook
## 27024694                      <NA>      <NA>          <NA>             <NA>
## 30969134                      <NA>      <NA>          <NA>             <NA>
## 30969136                      <NA>      <NA>          <NA>             <NA>
## 30969137                2025-08-01      <NA>          <NA>             <NA>
## 268980212                     <NA>       yes          <NA>             <NA>
## 293617257                     <NA>      <NA>          <NA>             <NA>
## 324671296                     <NA>       yes          <NA>             <NA>
## 324696522                     <NA>       yes          <NA>             <NA>
## 331413286                     <NA>       yes          <NA>             <NA>
## 334648390                     <NA>      <NA>          <NA>             <NA>
##           contact:instagram contact:phone contact:twitter contact:website
## 27024694               <NA>          <NA>            <NA>            <NA>
## 30969134               <NA>          <NA>            <NA>            <NA>
## 30969136               <NA>          <NA>            <NA>            <NA>
## 30969137               <NA>          <NA>            <NA>            <NA>
## 268980212              <NA>          <NA>            <NA>            <NA>
## 293617257              <NA>          <NA>            <NA>            <NA>
## 324671296              <NA>          <NA>            <NA>            <NA>
## 324696522              <NA>          <NA>            <NA>            <NA>
## 331413286              <NA>          <NA>            <NA>            <NA>
## 334648390              <NA>          <NA>            <NA>            <NA>
##           craft_beer cuisine delivery description diet:vegan diet:vegetarian
## 27024694        <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 30969134        <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 30969136        <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 30969137         yes    <NA>     <NA>        <NA>       <NA>             yes
## 268980212       <NA>    <NA>     <NA>        <NA>        yes             yes
## 293617257       <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 324671296       <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 324696522       <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 331413286       <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 334648390       <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
##            dog drive_in email entrance fhrs:authority fhrs:id
## 27024694  <NA>       no  <NA>     <NA>           <NA>    <NA>
## 30969134  <NA>     <NA>  <NA>     <NA>           <NA> 1816309
## 30969136  <NA>     <NA>  <NA>     <NA>           <NA> 1820273
## 30969137  <NA>     <NA>  <NA>     <NA>           <NA> 1819583
## 268980212 <NA>     <NA>  <NA>     <NA>           <NA> 1818907
## 293617257 <NA>     <NA>  <NA>     <NA>           <NA>    <NA>
## 324671296 <NA>     <NA>  <NA>     <NA>           <NA> 1820815
## 324696522 <NA>     <NA>  <NA>     <NA>           <NA>    <NA>
## 331413286 <NA>     <NA>  <NA>     <NA>           <NA> 1818994
## 334648390 <NA>     <NA>  <NA>     <NA>           <NA> 1816812
##           fhrs:local_authority_id fixme fixme:addr1 fixme:addr2 floor:material
## 27024694                     <NA>  <NA>        <NA>        <NA>           <NA>
## 30969134                     <NA>  <NA>        <NA>        <NA>           <NA>
## 30969136                     <NA>  <NA>        <NA>        <NA>           <NA>
## 30969137                     <NA>  <NA>        <NA>        <NA>           <NA>
## 268980212                    <NA>  <NA>        <NA>        <NA>           <NA>
## 293617257                    <NA>  <NA>        <NA>        <NA>           <NA>
## 324671296                    <NA>  <NA>        <NA>        <NA>           <NA>
## 324696522                    <NA>  <NA>        <NA>        <NA>           <NA>
## 331413286                    <NA>  <NA>        <NA>        <NA>           <NA>
## 334648390                    <NA>  <NA>        <NA>        <NA>           <NA>
##           food foot height indoor_seating internet_access internet_access:fee
## 27024694  <NA> <NA>   <NA>           <NA>            <NA>                <NA>
## 30969134  <NA> <NA>   <NA>           <NA>            <NA>                <NA>
## 30969136   yes <NA>   <NA>            yes            <NA>                <NA>
## 30969137   yes <NA>   <NA>           <NA>            <NA>                <NA>
## 268980212  yes <NA>   <NA>           <NA>            <NA>                <NA>
## 293617257 <NA> <NA>   <NA>           <NA>            <NA>                <NA>
## 324671296  yes <NA>   <NA>           <NA>            <NA>                <NA>
## 324696522 <NA> <NA>   <NA>           <NA>            <NA>                <NA>
## 331413286  yes <NA>   <NA>           <NA>            <NA>                <NA>
## 334648390 <NA> <NA>   <NA>           <NA>            <NA>                <NA>
##           level lgbtq lgbtq:gay lgbtq:women live_music lunch microbrewery
## 27024694   <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 30969134   <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 30969136   <NA>  <NA>      <NA>        <NA>        yes  <NA>         <NA>
## 30969137   <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 268980212  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 293617257  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 324671296  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 324696522  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 331413286  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 334648390  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
##           min_age not:addr:postcode not:operator:wikidata note note:name
## 27024694     <NA>              <NA>                  <NA> <NA>      <NA>
## 30969134     <NA>              <NA>              Q7619176 <NA>      <NA>
## 30969136     <NA>              <NA>                  <NA> <NA>      <NA>
## 30969137     <NA>              <NA>                  <NA> <NA>      <NA>
## 268980212    <NA>              <NA>                  <NA> <NA>      <NA>
## 293617257    <NA>              <NA>                  <NA> <NA>      <NA>
## 324671296    <NA>              <NA>                  <NA> <NA>      <NA>
## 324696522    <NA>              <NA>                  <NA> <NA>      <NA>
## 331413286    <NA>              <NA>                  <NA> <NA>      <NA>
## 334648390    <NA>              <NA>                  <NA> <NA>      <NA>
##           old_name
## 27024694      <NA>
## 30969134      <NA>
## 30969136      <NA>
## 30969137      <NA>
## 268980212     <NA>
## 293617257     <NA>
## 324671296     <NA>
## 324696522     <NA>
## 331413286     <NA>
## 334648390     <NA>
##                                                               opening_hours
## 27024694                                                               <NA>
## 30969134                                                               <NA>
## 30969136                                                               <NA>
## 30969137                                                               <NA>
## 268980212 Mo-Th 12:00-22:00, Fr 12:00-24:00, Sa 10:00-01:00, Su 10:00-21:00
## 293617257                                                              <NA>
## 324671296                                                              <NA>
## 324696522                                                              <NA>
## 331413286                                                              <NA>
## 334648390              Mo-We 11:30-02:00; Th-Sa 11:30-03:00; Su 12:00-02:00
##           opening_hours:signed  operator operator:wikidata organic
## 27024694                  <NA>      <NA>              <NA>    <NA>
## 30969134                  <NA> Stonegate              <NA>    <NA>
## 30969136                  <NA>      <NA>              <NA>    <NA>
## 30969137                    no      <NA>              <NA>    <NA>
## 268980212                 <NA> Stonegate          Q7619176    <NA>
## 293617257                 <NA>      <NA>              <NA>    <NA>
## 324671296                 <NA> Stonegate          Q7619176    <NA>
## 324696522                 <NA>      <NA>              <NA>    <NA>
## 331413286                 <NA> Stonegate          Q7619176    <NA>
## 334648390                 <NA>      <NA>              <NA>    <NA>
##           outdoor_seating panoramax panoramax:0 payment:american_express
## 27024694             <NA>      <NA>        <NA>                     <NA>
## 30969134             <NA>      <NA>        <NA>                     <NA>
## 30969136              yes      <NA>        <NA>                     <NA>
## 30969137             <NA>      <NA>        <NA>                     <NA>
## 268980212            <NA>      <NA>        <NA>                     <NA>
## 293617257            <NA>      <NA>        <NA>                     <NA>
## 324671296            <NA>      <NA>        <NA>                     <NA>
## 324696522            <NA>      <NA>        <NA>                     <NA>
## 331413286            <NA>      <NA>        <NA>                     <NA>
## 334648390            <NA>      <NA>        <NA>                     <NA>
##           payment:cards payment:cash payment:credit_cards payment:debit_cards
## 27024694           <NA>         <NA>                 <NA>                <NA>
## 30969134           <NA>         <NA>                 <NA>                <NA>
## 30969136           <NA>         <NA>                 <NA>                <NA>
## 30969137           <NA>         <NA>                 <NA>                <NA>
## 268980212          <NA>         <NA>                 <NA>                <NA>
## 293617257          <NA>         <NA>                 <NA>                <NA>
## 324671296          <NA>         <NA>                 <NA>                <NA>
## 324696522          <NA>         <NA>                 <NA>                <NA>
## 331413286          <NA>         <NA>                 <NA>                <NA>
## 334648390          <NA>         <NA>                 <NA>                <NA>
##           payment:mastercard payment:qr_code payment:visa phone real_ale
## 27024694                <NA>            <NA>         <NA>  <NA>     <NA>
## 30969134                <NA>            <NA>         <NA>  <NA>     <NA>
## 30969136                <NA>            <NA>         <NA>  <NA>     <NA>
## 30969137                <NA>            <NA>         <NA>  <NA>      yes
## 268980212               <NA>            <NA>         <NA>  <NA>     <NA>
## 293617257               <NA>            <NA>         <NA>  <NA>     <NA>
## 324671296               <NA>            <NA>         <NA>  <NA>      yes
## 324696522               <NA>            <NA>         <NA>  <NA>     <NA>
## 331413286               <NA>            <NA>         <NA>  <NA>      yes
## 334648390               <NA>            <NA>         <NA>  <NA>     <NA>
##           real_cider service:electricity smoking source   source:addr sport
## 27024694        <NA>                <NA>    <NA>   <NA> fhrs opendata  <NA>
## 30969134        <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 30969136        <NA>                <NA> outside   <NA>          <NA>  <NA>
## 30969137         yes                <NA>    <NA>   <NA>          <NA>  <NA>
## 268980212       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 293617257       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 324671296       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 324696522       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 331413286       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 334648390       <NA>                <NA> outside   <NA>          <NA>  <NA>
##           start_date surveillance survey:date takeaway theme toilets
## 27024694        <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 30969134        <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 30969136        <NA>         <NA>        <NA>     <NA>  <NA>     yes
## 30969137        <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 268980212       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 293617257       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 324671296       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 324696522       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 331413286       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 334648390       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
##           toilets:access toilets:female toilets:unisex toilets:wheelchair
## 27024694            <NA>           <NA>           <NA>               <NA>
## 30969134            <NA>           <NA>           <NA>               <NA>
## 30969136       customers           <NA>           <NA>               <NA>
## 30969137            <NA>           <NA>           <NA>               <NA>
## 268980212           <NA>           <NA>           <NA>               <NA>
## 293617257           <NA>           <NA>           <NA>               <NA>
## 324671296           <NA>           <NA>           <NA>               <NA>
## 324696522           <NA>           <NA>           <NA>               <NA>
## 331413286           <NA>           <NA>           <NA>               <NA>
## 334648390           <NA>           <NA>           <NA>               <NA>
##                                                             website
## 27024694                                                       <NA>
## 30969134        https://www.crafted-social.co.uk/footage-manchester
## 30969136                                                       <NA>
## 30969137                                                       <NA>
## 268980212                 https://www.slugandlettuce.co.uk/didsbury
## 293617257                                                      <NA>
## 324671296     https://www.slugandlettuce.co.uk/manchester-deansgate
## 324696522                                                      <NA>
## 331413286 https://www.slugandlettuce.co.uk/manchester-albert-square
## 334648390           https://www.revoluciondecuba.com/bar/manchester
##           website:booking wheelchair wheelchair:description wikidata wikipedia
## 27024694             <NA>       <NA>                   <NA>     <NA>      <NA>
## 30969134             <NA>         no                   <NA>     <NA>      <NA>
## 30969136             <NA>       <NA>                   <NA>     <NA>      <NA>
## 30969137             <NA>         no                   <NA>     <NA>      <NA>
## 268980212            <NA>       <NA>                   <NA>     <NA>      <NA>
## 293617257            <NA>       <NA>                   <NA>     <NA>      <NA>
## 324671296            <NA>       <NA>                   <NA>     <NA>      <NA>
## 324696522            <NA>        yes                   <NA>     <NA>      <NA>
## 331413286            <NA>        yes                   <NA>     <NA>      <NA>
## 334648390            <NA>        yes                   <NA>     <NA>      <NA>
##                             geometry
## 27024694   POINT (-2.23097 53.41074)
## 30969134  POINT (-2.236885 53.47016)
## 30969136  POINT (-2.240423 53.47363)
## 30969137   POINT (-2.23742 53.47425)
## 268980212  POINT (-2.231578 53.4191)
## 293617257  POINT (-2.23759 53.47497)
## 324671296 POINT (-2.246766 53.48295)
## 324696522 POINT (-2.250193 53.47549)
## 331413286 POINT (-2.246106 53.47924)
## 334648390 POINT (-2.248952 53.47832)
## 
## $osm_lines
## NULL
## 
## $osm_polygons
## Simple feature collection with 72 features and 68 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -2.704108 ymin: 53.35707 xmax: -2.005355 ymax: 53.64882
## Geodetic CRS:  WGS 84
## First 10 features:
##              osm_id            name access         addr:city addr:country
## 31894775   31894775          Common   <NA>        Manchester         <NA>
## 77808365   77808365   Squirrels Bar   <NA>              <NA>         <NA>
## 136006267 136006267        Fifteens   <NA>             Wigan         <NA>
## 183275512 183275512   Folk Cafe Bar   <NA>        Manchester         <NA>
## 183305127 183305127           Volta   <NA>        Manchester         <NA>
## 183750765 183750765            HAUS   <NA>              <NA>         <NA>
## 205672328 205672328   The Witchwood   <NA> Ashton-under-Lyne         <NA>
## 231022304 231022304 The Crooked Man   <NA>              <NA>         <NA>
## 231804597 231804597    Casa De Moor   <NA>         Stockport         <NA>
## 231833075 231833075   Heaton Social   <NA>         Stockport         <NA>
##           addr:housename addr:housenumber addr:postcode addr:province
## 31894775            <NA>            39-41        M4 1HW    Lancashire
## 77808365            <NA>             <NA>          <NA>          <NA>
## 136006267           <NA>               73       WN6 0HD          <NA>
## 183275512           <NA>          169-171       M20 2LN          <NA>
## 183305127           <NA>              167       M20 2LN          <NA>
## 183750765           <NA>              200       M20 2LW          <NA>
## 205672328           <NA>              152       OL6 7SF          <NA>
## 231022304           <NA>                7          <NA>          <NA>
## 231804597           <NA>               60       SK4 4NZ          <NA>
## 231833075           <NA>                3       SK4 4AG          <NA>
##                addr:street       addr:subdistrict addr:suburb amenity brand
## 31894775       Edge Street                   <NA>        <NA>     bar  <NA>
## 77808365              <NA>                   <NA>        <NA>     bar  <NA>
## 136006267      High Street Standish with Langtree    Standish     bar  <NA>
## 183275512      Burton Road                   <NA>        <NA>     bar  <NA>
## 183305127      Burton Road                   <NA>        <NA>     bar  <NA>
## 183750765      Burton Road                   <NA>        <NA>     bar  <NA>
## 205672328       Old Street                   <NA>        <NA>     bar  <NA>
## 231022304     Fairfax Road                   <NA>        <NA>     bar  <NA>
## 231804597 Heaton Moor Road                   <NA>        <NA>     bar  <NA>
## 231833075        Shaw Road                   <NA> Heaton Moor     bar  <NA>
##           brand:wikidata brewery building building:levels building:min_level
## 31894775            <NA>    <NA>      yes            <NA>               <NA>
## 77808365            <NA>    <NA>      yes            <NA>               <NA>
## 136006267           <NA>    <NA>      yes            <NA>               <NA>
## 183275512           <NA>    <NA>      yes            <NA>               <NA>
## 183305127           <NA>    <NA>      yes            <NA>               <NA>
## 183750765           <NA>    <NA>      yes            <NA>               <NA>
## 205672328           <NA>    <NA>     <NA>            <NA>               <NA>
## 231022304           <NA>    <NA>      yes            <NA>               <NA>
## 231804597           <NA>    <NA>      yes            <NA>               <NA>
## 231833075           <NA>    <NA>      yes            <NA>               <NA>
##           building:name building:part building:use check_date
## 31894775           <NA>          <NA>         <NA>       <NA>
## 77808365           <NA>          <NA>         <NA>       <NA>
## 136006267          <NA>          <NA>         <NA>       <NA>
## 183275512          <NA>          <NA>         <NA>       <NA>
## 183305127          <NA>          <NA>         <NA>       <NA>
## 183750765          <NA>          <NA>         <NA>       <NA>
## 205672328          <NA>          <NA>         <NA>       <NA>
## 231022304          <NA>          <NA>         <NA>       <NA>
## 231804597          <NA>          <NA>         <NA>       <NA>
## 231833075          <NA>          <NA>         <NA>       <NA>
##           check_date:opening_hours cocktails contact:facebook contact:instagram
## 31894775                      <NA>       yes             <NA>              <NA>
## 77808365                      <NA>      <NA>             <NA>              <NA>
## 136006267                     <NA>      <NA>             <NA>              <NA>
## 183275512                     <NA>      <NA>             <NA>              <NA>
## 183305127                     <NA>      <NA>             <NA>              <NA>
## 183750765                     <NA>      <NA>             <NA>              <NA>
## 205672328                     <NA>      <NA>             <NA>              <NA>
## 231022304                     <NA>      <NA>             <NA>              <NA>
## 231804597               2025-10-23      <NA>             <NA>              <NA>
## 231833075                     <NA>      <NA>             <NA>              <NA>
##              contact:phone                    contact:website craft_beer
## 31894775              <NA>                               <NA>        yes
## 77808365              <NA>                               <NA>       <NA>
## 136006267             <NA>                               <NA>       <NA>
## 183275512 +44 161 445 2912      http://www.folkcafebar.co.uk/       <NA>
## 183305127  +44 1614 488887 http://www.rhubarbrestaurant.co.uk       <NA>
## 183750765             <NA>                               <NA>       <NA>
## 205672328             <NA>                               <NA>       <NA>
## 231022304             <NA>                               <NA>       <NA>
## 231804597             <NA>                               <NA>       <NA>
## 231833075             <NA>                               <NA>       <NA>
##           cuisine description                 email fhrs:id food indoor_seating
## 31894775     <NA>        <NA>                  <NA>    <NA>  yes           <NA>
## 77808365     <NA>        <NA>                  <NA>    <NA> <NA>           <NA>
## 136006267    <NA>        <NA>                  <NA>    <NA> <NA>           <NA>
## 183275512    <NA>        <NA>                  <NA> 1818122  yes           <NA>
## 183305127 british        <NA>                  <NA> 1819076 <NA>           <NA>
## 183750765    <NA>        <NA>                  <NA> 1822049  yes           <NA>
## 205672328    <NA>        <NA>                  <NA> 1035549 <NA>           <NA>
## 231022304    <NA>        <NA>                  <NA>    <NA> <NA>           <NA>
## 231804597    <NA>        <NA>                  <NA>    <NA>  yes           <NA>
## 231833075    <NA>        <NA> palemoor1@outlook.com 1065743 <NA>           <NA>
##           internet_access level live_music min_age music old_fhrs:id old_name
## 31894775             wlan  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 77808365             <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 136006267            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 183275512            <NA>  <NA>       <NA>    <NA>  <NA>      756000     <NA>
## 183305127            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 183750765            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 205672328            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 231022304            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 231804597            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
## 231833075            <NA>  <NA>       <NA>    <NA>  <NA>        <NA>     <NA>
##                                                          opening_hours
## 31894775                                                          <NA>
## 77808365                                                          <NA>
## 136006267                                                         <NA>
## 183275512                                            Tu-Su 10:00-23:00
## 183305127 Mo off; Tu-Th 17:00-21:30; Fr-Sa 17:00-22:00; Su 13:00-21:00
## 183750765                                            Mo-Su 09:00-01:00
## 205672328                                                         <NA>
## 231022304                                                         <NA>
## 231804597                                                         <NA>
## 231833075                                            Tu-Su 16:00-00:00
##           opening_hours:signed operator operator:wikidata outdoor_seating owner
## 31894775                  <NA>     <NA>              <NA>            <NA>  <NA>
## 77808365                  <NA>     <NA>              <NA>            <NA>  <NA>
## 136006267                 <NA>     <NA>              <NA>            <NA>  <NA>
## 183275512                 <NA>     <NA>              <NA>             yes  <NA>
## 183305127                 <NA>     <NA>              <NA>            <NA>  <NA>
## 183750765                 <NA>     <NA>              <NA>             yes  <NA>
## 205672328                 <NA>     <NA>              <NA>            <NA>  <NA>
## 231022304                 <NA>     <NA>              <NA>            <NA>  <NA>
## 231804597                   no     <NA>              <NA>            <NA>  <NA>
## 231833075                 <NA>     <NA>              <NA>            <NA>  <NA>
##           owner:wikidata payment:cash payment:credit_cards payment:debit_cards
## 31894775            <NA>         <NA>                 <NA>                <NA>
## 77808365            <NA>         <NA>                 <NA>                <NA>
## 136006267           <NA>         <NA>                 <NA>                <NA>
## 183275512           <NA>         <NA>                 <NA>                <NA>
## 183305127           <NA>         <NA>                 <NA>                <NA>
## 183750765           <NA>         <NA>                 <NA>                <NA>
## 205672328           <NA>         <NA>                 <NA>                <NA>
## 231022304           <NA>         <NA>                 <NA>                <NA>
## 231804597           <NA>         <NA>                 <NA>                <NA>
## 231833075           <NA>         <NA>                 <NA>                <NA>
##                      phone real_ale                            ref:GB:uprn
## 31894775              <NA>      yes                                   <NA>
## 77808365              <NA>     <NA>                                   <NA>
## 136006267             <NA>     <NA>                                   <NA>
## 183275512             <NA>     <NA>                                   <NA>
## 183305127             <NA>     <NA>                   10091812371;77092833
## 183750765             <NA>      yes                                   <NA>
## 205672328 +44 161 344 0321     <NA>                                   <NA>
## 231022304             <NA>     <NA>                           100012688897
## 231804597             <NA>     <NA>                                   <NA>
## 231833075             <NA>     <NA> 100011519690;100012782121;100011519691
##           roof:levels roof:material smoking source source:addr source:name
## 31894775         <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 77808365         <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 136006267        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 183275512        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 183305127        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 183750765        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 205672328        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 231022304        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 231804597        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
## 231833075        <NA>          <NA>    <NA>   <NA>        <NA>        <NA>
##           toilets:wheelchair                            twitter
## 31894775                <NA>                               <NA>
## 77808365                <NA>                               <NA>
## 136006267               <NA>                               <NA>
## 183275512               <NA>                               <NA>
## 183305127               <NA>                               <NA>
## 183750765               <NA>                               <NA>
## 205672328               <NA>                               <NA>
## 231022304               <NA>                               <NA>
## 231804597               <NA>                               <NA>
## 231833075               <NA> https://twitter.com/paleheatonmoor
##                                       website wheelchair wheelchair:description
## 31894775                                 <NA>    limited                   <NA>
## 77808365                                 <NA>       <NA>                   <NA>
## 136006267                                <NA>    limited                   <NA>
## 183275512                                <NA>        yes                   <NA>
## 183305127                                <NA>       <NA>                   <NA>
## 183750765       https://www.hausdidsbury.com/       <NA>                   <NA>
## 205672328             http://thewitchwood.net       <NA>                   <NA>
## 231022304                                <NA>       <NA>                   <NA>
## 231804597 https://casademoor.com/heaton-moor/       <NA>                   <NA>
## 231833075                                <NA>       <NA>                   <NA>
##           wikidata                       geometry
## 31894775      <NA> POLYGON ((-2.235982 53.4844...
## 77808365      <NA> POLYGON ((-2.216829 53.4434...
## 136006267     <NA> POLYGON ((-2.661205 53.5848...
## 183275512     <NA> POLYGON ((-2.242833 53.4263...
## 183305127     <NA> POLYGON ((-2.242687 53.4265...
## 183750765     <NA> POLYGON ((-2.242799 53.4269...
## 205672328 Q7775324 POLYGON ((-2.099437 53.4862...
## 231022304     <NA> POLYGON ((-2.285096 53.5339...
## 231804597     <NA> POLYGON ((-2.182471 53.4236...
## 231833075     <NA> POLYGON ((-2.184632 53.4228...

Saving only the points:

osm_bar_sf <- osm_bar_sf$osm_points
head(osm_bar_sf)
## Simple feature collection with 6 features and 118 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -2.240422 ymin: 53.41074 xmax: -2.23097 ymax: 53.47497
## Geodetic CRS:  WGS 84
##              osm_id              name access  addr:city addr:country
## 27024694   27024694 Didsbury Junction   <NA> Manchester           GB
## 30969134   30969134     The Grosvenor   <NA> Manchester         <NA>
## 30969136   30969136        Revolution   <NA> Manchester           GB
## 30969137   30969137     Joshua Brooks   <NA> Manchester         <NA>
## 268980212 268980212    Slug & Lettuce   <NA> Manchester         <NA>
## 293617257 293617257   Fifth Nightclub   <NA> Manchester           GB
##           addr:county addr:floor addr:housename addr:housenumber addr:place
## 27024694         <NA>       <NA>           <NA>          844-846   Didsbury
## 30969134         <NA>       <NA>    The Footage             <NA>       <NA>
## 30969136         <NA>       <NA>           <NA>            88-94       <NA>
## 30969137         <NA>       <NA>           <NA>              106       <NA>
## 268980212        <NA>       <NA>           <NA>              651       <NA>
## 293617257        <NA>       <NA>           <NA>              121       <NA>
##           addr:postcode addr:state      addr:street addr:subdistrict
## 27024694        M20 2RN       <NA>    Wilmslow Road             <NA>
## 30969134         M1 7DZ       <NA> Grosvenor Street             <NA>
## 30969136         M1 5WH       <NA>    Oxford Street             <NA>
## 30969137         M1 6NG       <NA>  Princess Street             <NA>
## 268980212       M20 6QZ       <NA>    Wilmslow Road             <NA>
## 293617257        M1 7AG       <NA>  Princess Street             <NA>
##           addr:suburb addr:town addr:unit air_conditioning alt_name amenity
## 27024694         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 30969134         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 30969136         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 30969137         <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 268980212        <NA>      <NA>      <NA>             <NA>     <NA>     bar
## 293617257        <NA>      <NA>      <NA>             <NA>     <NA>     bar
##           amenity_1  bar barrier branch            brand brand:wikidata
## 27024694       <NA> <NA>    <NA>   <NA>             <NA>           <NA>
## 30969134       <NA> <NA>    <NA>   <NA>             <NA>           <NA>
## 30969136       <NA> <NA>    <NA>   <NA>       Revolution      Q64024398
## 30969137       <NA> <NA>    <NA>   <NA>             <NA>           <NA>
## 268980212      <NA> <NA>    <NA>   <NA> Slug and Lettuce       Q7542224
## 293617257      <NA> <NA>    <NA>   <NA>             <NA>           <NA>
##           brand:wikipedia breakfast brewery building changing_table
## 27024694             <NA>      <NA>    <NA>     <NA>           <NA>
## 30969134             <NA>      <NA>    <NA>     <NA>           <NA>
## 30969136             <NA>      <NA>    <NA>     <NA>           <NA>
## 30969137             <NA>      <NA>    <NA>     <NA>           <NA>
## 268980212            <NA>      <NA>    <NA>     <NA>           <NA>
## 293617257            <NA>      <NA>    <NA>     <NA>           <NA>
##           changing_table:count changing_table:location check_date
## 27024694                  <NA>                    <NA>       <NA>
## 30969134                  <NA>                    <NA>       <NA>
## 30969136                  <NA>                    <NA> 2025-08-14
## 30969137                  <NA>                    <NA>       <NA>
## 268980212                 <NA>                    <NA>       <NA>
## 293617257                 <NA>                    <NA>       <NA>
##           check_date:opening_hours cocktails contact:email contact:facebook
## 27024694                      <NA>      <NA>          <NA>             <NA>
## 30969134                      <NA>      <NA>          <NA>             <NA>
## 30969136                      <NA>      <NA>          <NA>             <NA>
## 30969137                2025-08-01      <NA>          <NA>             <NA>
## 268980212                     <NA>       yes          <NA>             <NA>
## 293617257                     <NA>      <NA>          <NA>             <NA>
##           contact:instagram contact:phone contact:twitter contact:website
## 27024694               <NA>          <NA>            <NA>            <NA>
## 30969134               <NA>          <NA>            <NA>            <NA>
## 30969136               <NA>          <NA>            <NA>            <NA>
## 30969137               <NA>          <NA>            <NA>            <NA>
## 268980212              <NA>          <NA>            <NA>            <NA>
## 293617257              <NA>          <NA>            <NA>            <NA>
##           craft_beer cuisine delivery description diet:vegan diet:vegetarian
## 27024694        <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 30969134        <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 30969136        <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
## 30969137         yes    <NA>     <NA>        <NA>       <NA>             yes
## 268980212       <NA>    <NA>     <NA>        <NA>        yes             yes
## 293617257       <NA>    <NA>     <NA>        <NA>       <NA>            <NA>
##            dog drive_in email entrance fhrs:authority fhrs:id
## 27024694  <NA>       no  <NA>     <NA>           <NA>    <NA>
## 30969134  <NA>     <NA>  <NA>     <NA>           <NA> 1816309
## 30969136  <NA>     <NA>  <NA>     <NA>           <NA> 1820273
## 30969137  <NA>     <NA>  <NA>     <NA>           <NA> 1819583
## 268980212 <NA>     <NA>  <NA>     <NA>           <NA> 1818907
## 293617257 <NA>     <NA>  <NA>     <NA>           <NA>    <NA>
##           fhrs:local_authority_id fixme fixme:addr1 fixme:addr2 floor:material
## 27024694                     <NA>  <NA>        <NA>        <NA>           <NA>
## 30969134                     <NA>  <NA>        <NA>        <NA>           <NA>
## 30969136                     <NA>  <NA>        <NA>        <NA>           <NA>
## 30969137                     <NA>  <NA>        <NA>        <NA>           <NA>
## 268980212                    <NA>  <NA>        <NA>        <NA>           <NA>
## 293617257                    <NA>  <NA>        <NA>        <NA>           <NA>
##           food foot height indoor_seating internet_access internet_access:fee
## 27024694  <NA> <NA>   <NA>           <NA>            <NA>                <NA>
## 30969134  <NA> <NA>   <NA>           <NA>            <NA>                <NA>
## 30969136   yes <NA>   <NA>            yes            <NA>                <NA>
## 30969137   yes <NA>   <NA>           <NA>            <NA>                <NA>
## 268980212  yes <NA>   <NA>           <NA>            <NA>                <NA>
## 293617257 <NA> <NA>   <NA>           <NA>            <NA>                <NA>
##           level lgbtq lgbtq:gay lgbtq:women live_music lunch microbrewery
## 27024694   <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 30969134   <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 30969136   <NA>  <NA>      <NA>        <NA>        yes  <NA>         <NA>
## 30969137   <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 268980212  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
## 293617257  <NA>  <NA>      <NA>        <NA>       <NA>  <NA>         <NA>
##           min_age not:addr:postcode not:operator:wikidata note note:name
## 27024694     <NA>              <NA>                  <NA> <NA>      <NA>
## 30969134     <NA>              <NA>              Q7619176 <NA>      <NA>
## 30969136     <NA>              <NA>                  <NA> <NA>      <NA>
## 30969137     <NA>              <NA>                  <NA> <NA>      <NA>
## 268980212    <NA>              <NA>                  <NA> <NA>      <NA>
## 293617257    <NA>              <NA>                  <NA> <NA>      <NA>
##           old_name
## 27024694      <NA>
## 30969134      <NA>
## 30969136      <NA>
## 30969137      <NA>
## 268980212     <NA>
## 293617257     <NA>
##                                                               opening_hours
## 27024694                                                               <NA>
## 30969134                                                               <NA>
## 30969136                                                               <NA>
## 30969137                                                               <NA>
## 268980212 Mo-Th 12:00-22:00, Fr 12:00-24:00, Sa 10:00-01:00, Su 10:00-21:00
## 293617257                                                              <NA>
##           opening_hours:signed  operator operator:wikidata organic
## 27024694                  <NA>      <NA>              <NA>    <NA>
## 30969134                  <NA> Stonegate              <NA>    <NA>
## 30969136                  <NA>      <NA>              <NA>    <NA>
## 30969137                    no      <NA>              <NA>    <NA>
## 268980212                 <NA> Stonegate          Q7619176    <NA>
## 293617257                 <NA>      <NA>              <NA>    <NA>
##           outdoor_seating panoramax panoramax:0 payment:american_express
## 27024694             <NA>      <NA>        <NA>                     <NA>
## 30969134             <NA>      <NA>        <NA>                     <NA>
## 30969136              yes      <NA>        <NA>                     <NA>
## 30969137             <NA>      <NA>        <NA>                     <NA>
## 268980212            <NA>      <NA>        <NA>                     <NA>
## 293617257            <NA>      <NA>        <NA>                     <NA>
##           payment:cards payment:cash payment:credit_cards payment:debit_cards
## 27024694           <NA>         <NA>                 <NA>                <NA>
## 30969134           <NA>         <NA>                 <NA>                <NA>
## 30969136           <NA>         <NA>                 <NA>                <NA>
## 30969137           <NA>         <NA>                 <NA>                <NA>
## 268980212          <NA>         <NA>                 <NA>                <NA>
## 293617257          <NA>         <NA>                 <NA>                <NA>
##           payment:mastercard payment:qr_code payment:visa phone real_ale
## 27024694                <NA>            <NA>         <NA>  <NA>     <NA>
## 30969134                <NA>            <NA>         <NA>  <NA>     <NA>
## 30969136                <NA>            <NA>         <NA>  <NA>     <NA>
## 30969137                <NA>            <NA>         <NA>  <NA>      yes
## 268980212               <NA>            <NA>         <NA>  <NA>     <NA>
## 293617257               <NA>            <NA>         <NA>  <NA>     <NA>
##           real_cider service:electricity smoking source   source:addr sport
## 27024694        <NA>                <NA>    <NA>   <NA> fhrs opendata  <NA>
## 30969134        <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 30969136        <NA>                <NA> outside   <NA>          <NA>  <NA>
## 30969137         yes                <NA>    <NA>   <NA>          <NA>  <NA>
## 268980212       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
## 293617257       <NA>                <NA>    <NA>   <NA>          <NA>  <NA>
##           start_date surveillance survey:date takeaway theme toilets
## 27024694        <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 30969134        <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 30969136        <NA>         <NA>        <NA>     <NA>  <NA>     yes
## 30969137        <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 268980212       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
## 293617257       <NA>         <NA>        <NA>     <NA>  <NA>    <NA>
##           toilets:access toilets:female toilets:unisex toilets:wheelchair
## 27024694            <NA>           <NA>           <NA>               <NA>
## 30969134            <NA>           <NA>           <NA>               <NA>
## 30969136       customers           <NA>           <NA>               <NA>
## 30969137            <NA>           <NA>           <NA>               <NA>
## 268980212           <NA>           <NA>           <NA>               <NA>
## 293617257           <NA>           <NA>           <NA>               <NA>
##                                                       website website:booking
## 27024694                                                 <NA>            <NA>
## 30969134  https://www.crafted-social.co.uk/footage-manchester            <NA>
## 30969136                                                 <NA>            <NA>
## 30969137                                                 <NA>            <NA>
## 268980212           https://www.slugandlettuce.co.uk/didsbury            <NA>
## 293617257                                                <NA>            <NA>
##           wheelchair wheelchair:description wikidata wikipedia
## 27024694        <NA>                   <NA>     <NA>      <NA>
## 30969134          no                   <NA>     <NA>      <NA>
## 30969136        <NA>                   <NA>     <NA>      <NA>
## 30969137          no                   <NA>     <NA>      <NA>
## 268980212       <NA>                   <NA>     <NA>      <NA>
## 293617257       <NA>                   <NA>     <NA>      <NA>
##                             geometry
## 27024694   POINT (-2.23097 53.41074)
## 30969134  POINT (-2.236885 53.47016)
## 30969136  POINT (-2.240423 53.47363)
## 30969137   POINT (-2.23742 53.47425)
## 268980212  POINT (-2.231578 53.4191)
## 293617257  POINT (-2.23759 53.47497)

Too much data! Filtering to exclude blanks

osm_bar_sf <- osm_bar_sf |> filter(!is.na(name))
dim(osm_bar_sf)
## [1] 325 119

We are still left with 325 bars in our data.

Attribute operations

The function filter() is an attribute operation because it enabled us to make changes to the data by manipulating elements in the attribute table.

Further filtering the data to include only a particular violent crime:

unique(crimes$crime_type)
##  [1] "Anti-social behaviour"        "Violence and sexual offences"
##  [3] "Criminal damage and arson"    "Other theft"                 
##  [5] "Vehicle crime"                "Burglary"                    
##  [7] "Public order"                 "Shoplifting"                 
##  [9] "Other crime"                  "Possession of weapons"       
## [11] "Theft from the person"        "Bicycle theft"               
## [13] "Robbery"                      "Drugs"
crimes <- crimes |> 
  filter(crime_type == "Violence and sexual offences")

Spatial operations

Reprojecting coordinates

Checking the CRS of our crimes data:

st_crs(crimes)
## Coordinate Reference System: NA

There is no CRS because crimes data is not a spatial object (yet)

Converting crimes to a spatial object:

crimes <- crimes |> st_as_sf(
  coords = c("longitude", "latitude"),
  crs = 4326,
  agr = "constant",
  na.fail = FALSE
)

Here are the attributes for the agr parameter: - "constant": attributes that are constant throughout the geometry (like land use).
- "aggregate": used when the attribute is an aggregate value (like population count or population density).
- "identity": used when the attributes uniquely identifies the geometry of the the object we are interested in, like building ID, or city name.

Checking the CRS of crime once again:

st_crs(crimes)
## Coordinate Reference System:
##   User input: EPSG:4326 
##   wkt:
## GEOGCRS["WGS 84",
##     ENSEMBLE["World Geodetic System 1984 ensemble",
##         MEMBER["World Geodetic System 1984 (Transit)"],
##         MEMBER["World Geodetic System 1984 (G730)"],
##         MEMBER["World Geodetic System 1984 (G873)"],
##         MEMBER["World Geodetic System 1984 (G1150)"],
##         MEMBER["World Geodetic System 1984 (G1674)"],
##         MEMBER["World Geodetic System 1984 (G1762)"],
##         MEMBER["World Geodetic System 1984 (G2139)"],
##         MEMBER["World Geodetic System 1984 (G2296)"],
##         ELLIPSOID["WGS 84",6378137,298.257223563,
##             LENGTHUNIT["metre",1]],
##         ENSEMBLEACCURACY[2.0]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433]],
##     CS[ellipsoidal,2],
##         AXIS["geodetic latitude (Lat)",north,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433]],
##         AXIS["geodetic longitude (Lon)",east,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433]],
##     USAGE[
##         SCOPE["Horizontal component of 3D system."],
##         AREA["World."],
##         BBOX[-90,-180,90,180]],
##     ID["EPSG",4326]]

Checking the CRS of city_center:

st_crs(city_center)
## Coordinate Reference System:
##   User input: OSGB36 / British National Grid 
##   wkt:
## PROJCRS["OSGB36 / British National Grid",
##     BASEGEOGCRS["OSGB36",
##         DATUM["Ordnance Survey of Great Britain 1936",
##             ELLIPSOID["Airy 1830",6377563.396,299.3249646,
##                 LENGTHUNIT["metre",1]]],
##         PRIMEM["Greenwich",0,
##             ANGLEUNIT["degree",0.0174532925199433]],
##         ID["EPSG",4277]],
##     CONVERSION["British National Grid",
##         METHOD["Transverse Mercator",
##             ID["EPSG",9807]],
##         PARAMETER["Latitude of natural origin",49,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8801]],
##         PARAMETER["Longitude of natural origin",-2,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8802]],
##         PARAMETER["Scale factor at natural origin",0.9996012717,
##             SCALEUNIT["unity",1],
##             ID["EPSG",8805]],
##         PARAMETER["False easting",400000,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8806]],
##         PARAMETER["False northing",-100000,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8807]]],
##     CS[Cartesian,2],
##         AXIS["(E)",east,
##             ORDER[1],
##             LENGTHUNIT["metre",1]],
##         AXIS["(N)",north,
##             ORDER[2],
##             LENGTHUNIT["metre",1]],
##     USAGE[
##         SCOPE["Engineering survey, topographic mapping."],
##         AREA["United Kingdom (UK) - offshore to boundary of UKCS within 49°45'N to 61°N and 9°W to 2°E; onshore Great Britain (England, Wales and Scotland). Isle of Man onshore."],
##         BBOX[49.75,-9.01,61.01,2.01]],
##     ID["EPSG",27700]]

The city_center uses a different CRS.

Re-projecting the CRS of city_center to WGS84 using st_transform():

city_center <- st_transform(city_center, crs = 4326)

Checking if the projections are now similar:

st_crs(crimes) == st_crs(city_center)
## [1] TRUE

Checking the CRS of the osm_bar_sf data from Open Street Map:

st_crs(osm_bar_sf)
## Coordinate Reference System:
##   User input: EPSG:4326 
##   wkt:
## GEOGCRS["WGS 84",
##     ENSEMBLE["World Geodetic System 1984 ensemble",
##         MEMBER["World Geodetic System 1984 (Transit)"],
##         MEMBER["World Geodetic System 1984 (G730)"],
##         MEMBER["World Geodetic System 1984 (G873)"],
##         MEMBER["World Geodetic System 1984 (G1150)"],
##         MEMBER["World Geodetic System 1984 (G1674)"],
##         MEMBER["World Geodetic System 1984 (G1762)"],
##         ELLIPSOID["WGS 84",6378137,298.257223563,
##             LENGTHUNIT["metre",1]],
##         ENSEMBLEACCURACY[2.0]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433]],
##     CS[ellipsoidal,2],
##         AXIS["geodetic latitude (Lat)",north,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433]],
##         AXIS["geodetic longitude (Lon)",east,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433]],
##     USAGE[
##         SCOPE["Horizontal component of 3D system."],
##         AREA["World."],
##         BBOX[-90,-180,90,180]],
##     ID["EPSG",4326]]

Now all data sources have matching CRS!

Subsetting points

Plotting osm_bar_sf and city_center geometries:

plot(st_geometry(osm_bar_sf), col = "red")
plot(st_geometry(city_center), add = TRUE)
May bars fall outside the City Center ward

May bars fall outside the City Center ward

Plotting osm_bar_sf, crimes, and city_center geometries:

plot(st_geometry(osm_bar_sf), col = "red")
plot(st_geometry(crimes), col = "blue", add = TRUE)
plot(st_geometry(city_center), add = TRUE)
Most crimes fall outside the City Center ward

Most crimes fall outside the City Center ward

Getting the intersection of city_center and crimes geometries:

cc_crimes <- st_intersects(city_center, crimes)

Subsetting crimes using the result of st_intersects():

cc_crimes <- crimes[unlist(cc_crimes),]
head(cc_crimes)
## Simple feature collection with 6 features and 10 fields
## Attribute-geometry relationships: constant (10)
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -2.248958 ymin: 53.48214 xmax: -2.238637 ymax: 53.48675
## Geodetic CRS:  WGS 84
## # A tibble: 6 × 11
##   crime_id           month reported_by falls_within location lsoa_code lsoa_name
##   <chr>              <chr> <chr>       <chr>        <chr>    <chr>     <chr>    
## 1 5a4de7fc0da3294db… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 2 98f7f39a9437d17ca… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 3 e8c5555dc4a9b9fdc… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 4 6c1bc711333e498f1… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 5 a42d88a2f8e9d9b87… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 6 ffe16234ce35bbc91… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## # ℹ 4 more variables: crime_type <chr>, last_outcome_category <chr>,
## #   context <lgl>, geometry <POINT [°]>

Plotting city_center and cc_crimes geometries:

plot(st_geometry(city_center))
plot(st_geometry(cc_crimes), col = "blue", add = TRUE)
Crimes inside the City Center ward

Crimes inside the City Center ward

Applying the same concept for the bars in Manchester:

cc_bars <- st_intersects(city_center, osm_bar_sf)
cc_bars <- osm_bar_sf[unlist(cc_bars), ]

Plotting the three geometries again:

plot(st_geometry(city_center))
plot(st_geometry(cc_bars), col = "red", add = TRUE)
plot(st_geometry(cc_crimes), col = "blue", add = TRUE)
Bars and crimes within the City Center

Bars and crimes within the City Center

How do we connect the crimes to the bars then?

Building buffers

One approach to answer the question above is to build a buffer around the bars, and count all the crimes that fall within a specific radius of this bar.

Trying the st_buffer() function:

prem_buffer <- st_buffer(cc_bars, 1)

This works but it does not make much sense since the current CRS uses “degrees” instead of direct length units. The function created buffers of 1 degree around the bars.

Transforming the CRS of bars to BNG (British National Grid) first, before buffering with a radius of 400m:

bars_bng <- st_transform(cc_bars, crs = 27700) # code for BNG is 27700
bars_buffer <- st_buffer(bars_bng, 400)

Plotting:

plot(st_geometry(bars_buffer))
plot(st_geometry(bars_bng), add = TRUE)
Bars with 400m buffers

Bars with 400m buffers

There are a lot of overlaps here, since there are many bars in the area. Choosing a buffering radius of 100 meters:

bar_buffer_100 <- st_buffer(bars_bng, 100)

# plotting
plot(st_geometry(bar_buffer_100))
plot(st_geometry(bars_bng), add = TRUE)

Transforming the buffer data back to WGS84:

buffer_WGS84 <- st_transform(bar_buffer_100, crs = 4326)

Plotting once more:

plot(st_geometry(buffer_WGS84))
plot(st_geometry(cc_crimes), col = "blue", add = TRUE)
Crimes around the 100m buffer polygons

Crimes around the 100m buffer polygons

How many crimes occur within the buffer polygons?

Counting points within a polygon

In computational geometry, the question above falls under the point-in-polygon problem category.

Joining the buffer data to cc_crimes data and creating a frequency table of the number of crimes within the buffer of each bar:

crimes_per_prem <- st_join(buffer_WGS84, cc_crimes, left = FALSE) |> 
  count(name)

head(crimes_per_prem)
## Simple feature collection with 6 features and 2 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -2.251548 ymin: 53.47374 xmax: -2.232572 ymax: 53.4832
## Geodetic CRS:  WGS 84
##               name  n                       geometry
## 1               33 21 POLYGON ((-2.23473 53.48235...
## 2              ARK  1 POLYGON ((-2.248537 53.4746...
## 3 Albert's Schloss 13 POLYGON ((-2.246406 53.4782...
## 4      All Bar One  3 POLYGON ((-2.241114 53.481,...
## 5        Allotment 23 POLYGON ((-2.232574 53.4816...
## 6       Arcane Bar  9 POLYGON ((-2.245908 53.4810...

Inspecting which premises have the most violent crimes:

crimes_per_prem |> 
  select(name, n) |> 
  arrange(desc(n))
## Simple feature collection with 115 features and 2 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: -2.25777 ymin: 53.47262 xmax: -2.220188 ymax: 53.48615
## Geodetic CRS:  WGS 84
## First 10 features:
##                 name  n                       geometry
## 1         Crafty Pig 59 POLYGON ((-2.234923 53.4819...
## 2       Centre Stage 32 POLYGON ((-2.236641 53.4769...
## 3               Dive 31 POLYGON ((-2.234829 53.4822...
## 4              G-A-Y 30 POLYGON ((-2.236429 53.4765...
## 5  On Bar Manchester 30 POLYGON ((-2.236242 53.4766...
## 6               NQ64 25 MULTIPOLYGON (((-2.246766 5...
## 7               Mala 24 POLYGON ((-2.233471 53.4820...
## 8        Night & Day 24 POLYGON ((-2.233702 53.4827...
## 9          Allotment 23 POLYGON ((-2.232574 53.4816...
## 10              Noho 22 POLYGON ((-2.232927 53.4826...

Since there are overlapping buffer regions, there might be plenty of double-counting here.

Finding the nearest point

To overcome this double-counting issue, we can assign each crime point to the closest possible bar.

Getting the nearest bar to crime data point using st_nearest_feature():

crime_w_bars <- cc_crimes |> 
  mutate(nearest_bar = cc_bars[st_nearest_feature(cc_crimes, cc_bars), 2])

head(crime_w_bars)
## Simple feature collection with 6 features and 11 fields
## Attribute-geometry relationships: constant (10), NA's (1)
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -2.248958 ymin: 53.48214 xmax: -2.238637 ymax: 53.48675
## Geodetic CRS:  WGS 84
## # A tibble: 6 × 12
##   crime_id           month reported_by falls_within location lsoa_code lsoa_name
##   <chr>              <chr> <chr>       <chr>        <chr>    <chr>     <chr>    
## 1 5a4de7fc0da3294db… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 2 98f7f39a9437d17ca… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 3 e8c5555dc4a9b9fdc… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 4 6c1bc711333e498f1… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 5 a42d88a2f8e9d9b87… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## 6 ffe16234ce35bbc91… 2019… Greater Ma… Greater Man… On or n… E01033658 Manchest…
## # ℹ 5 more variables: crime_type <chr>, last_outcome_category <chr>,
## #   context <lgl>, geometry <POINT [°]>, nearest_bar <sf[,2]>

Removing the geometry data at this point:

crimes_per_prem_2 <- crime_w_bars |> 
  st_drop_geometry() |> 
  group_by(nearest_bar$name) |> 
  summarize(num_crimes = n()) |> 
  rename(name = `nearest_bar$name`)

head(crimes_per_prem_2)
## # A tibble: 6 × 2
##   name             num_crimes
##   <chr>                 <int>
## 1 33                        3
## 2 Albert's Schloss         10
## 3 All Bar One               1
## 4 Allotment                 1
## 5 Arcane Bar                7
## 6 Area                      2

Joining this data to cc_bars:

crimes_per_prem_2 <-left_join(
  cc_bars, crimes_per_prem_2, 
  by = c("name" = "name")
)

Looking at the bar with the most crimes now:

crimes_per_prem_2 |> 
  select(name, num_crimes) |> 
  arrange(desc(num_crimes))
## Simple feature collection with 132 features and 2 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -2.256285 ymin: 53.47278 xmax: -2.221694 ymax: 53.48525
## Geodetic CRS:  WGS 84
## First 10 features:
##                       name num_crimes                   geometry
## 1               Crafty Pig         50 POINT (-2.236427 53.48185)
## 2                     NQ64         20  POINT (-2.24827 53.47824)
## 3                     NQ64         20 POINT (-2.236719 53.48249)
## 4    Bliss Club Manchester         14 POINT (-2.247691 53.47476)
## 5             Centre Stage         13 POINT (-2.238146 53.47691)
## 6                     Mala         12 POINT (-2.234975 53.48201)
## 7         Albert's Schloss         10   POINT (-2.24791 53.4782)
## 8                    SIXES          9 POINT (-2.243594 53.48512)
## 9  The Salmon Of Knowledge          8 POINT (-2.233841 53.48236)
## 10                Chill#96          8 POINT (-2.240749 53.47734)

Which of the two approaches is better? it depends on the case.

Using the second approach, double-counting is avoided, at the expense of attributing the crime to the nearest bar. This too, may not be a fair assumption to make, since drunk people do illogical things.

Measuring distances

Looking closely at Crafty Pig:

cp <- cc_bars |> 
  filter(name == "Crafty Pig")

cp_buffer <- bar_buffer_100 |>
  filter(name == "Crafty Pig") |> 
  st_transform(4326)

cp_crimes <- crime_w_bars |> 
  filter(nearest_bar$name == "Crafty Pig")

Using mapply() and st_union() functions to draw a line between each crime and the Crafty Pig bar:

dist_lines <- st_sfc(
  mapply(
    function(a, b){
      st_cast(st_union(a, b), "LINESTRING") # specify function
    },
    cp_crimes$geometry, # input a for the function
    cp_crimes$nearest_bar$geometry, # input b for the function
    SIMPLIFY = FALSE # don't attempt to reduce the result
  )
)

Note: the st_sfc() is used to create a simple feature geometry list column.

Plotting:

plot(st_geometry(cp_buffer))
plot(st_geometry(cp), col = "black", add = TRUE)
plot(st_geometry(cp_crimes), col = "blue", add = TRUE)
plot(st_geometry(dist_lines), col = "green", add = TRUE)

All the crimes happened at only one location, which is within the 100m buffer. How far exactly?

cp_crimes <- cp_crimes |> 
  mutate(distance = st_distance(geometry, nearest_bar$geometry))

Arranging:

cp_crimes$distance[1:4]
## Units: [m]
## [1] 67.09451 67.09451 67.09451 67.09451

Why is it that all these crimes are geo-coded to one single location? This is due to geo-masking of data, to ensure anonymity.

Plotting interactive maps with leaflet

m <- leaflet() |> 
  addTiles() |> 
  addMarkers(
    lng=-2.230899,  # longitude
    lat=53.464987,  # latitude
    popup="University of Manchester"
  )

m

Adding multiple points:

latitudes = c(53.464987, 53.472726, 53.466649) 
longitudes = c(-2.230899, -2.245481, -2.243421)
popups = c("You are here", "Here is another point", "Here is another point")

df <- data.frame(latitudes, longitudes, popups)

m <- leaflet(data = df) |> 
  addTiles() |> 
  addMarkers(
    lng = ~longitudes,
    lat = ~latitudes,
    popup = ~popups
  )

m

Creating a color palette using colorBin():

pal <- colorBin(
  "RdPu", 
  domain = crimes_per_prem$n, # what value to use for shading
  bins = 5,
  pretty = TRUE
) 

Using the created color bin to color polygons that on a leaflet map:

leaflet(crimes_per_prem) |> 
  addTiles() |> 
  addPolygons(
    fillColor = ~pal(n),
    fillOpacity = 0.8,
    weight = 1,
    opacity = 1,
    color = "black",
    label = ~as.character(name)
  ) |> 
  addLegend(
    pal = pal,
    values = ~n,
    opacity = 0.7,
    title = "Violent crimes",
    position = "bottomright"
  )

Geocoding

Creating an address to geocode:

addresses <- data.frame(
  name = "Sherlock Holmes",
  address = "221B Baker Street, London, UK"
)

Using the function geocode() function from geocoder package to get the coordinates for the address above:

addresses |> geocode(address, method = "osm")
## Passing 1 address to the Nominatim single address geocoder
## Query completed in: 1.2 seconds
## # A tibble: 1 × 4
##   name            address                         lat   long
##   <chr>           <chr>                         <dbl>  <dbl>
## 1 Sherlock Holmes 221B Baker Street, London, UK  51.5 -0.158

Geocoding on a bigger scale

Getting data about different alcohol outlets via the Licensed Premises dataset:

data_url <- "http://www.manchester.gov.uk/open/download/downloads/id/169/licensed_premises.csv"

lic_prem <- read_csv(data_url) |> clean_names()
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
##   dat <- vroom(...)
##   problems(dat)
## Rows: 65535 Columns: 36
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (23): EXTRACTDATE, ORGANISATIONURI, ORGANISATIONLABEL, CASEDATE, SERVICE...
## dbl  (1): CASEREFERENCE
## lgl (12): LATENIGHTREFRESHMENT, ALCOHOLSUPPLY, OPENINGHOURS, LICENCEENDDATE,...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(lic_prem)
## # A tibble: 6 × 36
##   extractdate organisationuri           organisationlabel casereference casedate
##   <chr>       <chr>                     <chr>                     <dbl> <chr>   
## 1 10/10/2014  http://opendatacommuniti… Manchester                 1565 07/03/2…
## 2 10/10/2014  http://opendatacommuniti… Manchester                 1823 25/03/2…
## 3 10/10/2014  http://opendatacommuniti… Manchester                 1824 24/03/2…
## 4 10/10/2014  http://opendatacommuniti… Manchester                 1826 24/03/2…
## 5 10/10/2014  http://opendatacommuniti… Manchester                 1834 11/04/2…
## 6 10/10/2014  http://opendatacommuniti… Manchester                 1841 07/04/2…
## # ℹ 31 more variables: servicetypeuri <chr>, servicetypelabel <chr>,
## #   premisesname <chr>, locationtext <chr>, postcode <chr>,
## #   entertainmenttypeuri <chr>, entertainmenttypelabel <chr>,
## #   latenightrefreshment <lgl>, alcoholsupply <lgl>, openinghours <lgl>,
## #   statusuri <chr>, statuslabel <chr>, licencestartdate <chr>,
## #   licenceenddate <lgl>, onpremisesalcoholsale <lgl>,
## #   offpremisesalcoholsale <lgl>, licenceholder <chr>, …
glimpse(lic_prem)
## Rows: 65,535
## Columns: 36
## $ extractdate                  <chr> "10/10/2014", "10/10/2014", "10/10/2014",…
## $ organisationuri              <chr> "http://opendatacommunities.org/id/metrop…
## $ organisationlabel            <chr> "Manchester", "Manchester", "Manchester",…
## $ casereference                <dbl> 1565, 1823, 1824, 1826, 1834, 1841, 1854,…
## $ casedate                     <chr> "07/03/2005", "25/03/2005", "24/03/2005",…
## $ servicetypeuri               <chr> "http://id.esd.org.uk/service/860", "http…
## $ servicetypelabel             <chr> "Premises Licence", "Club Premises Certif…
## $ premisesname                 <chr> "Fresh & Frozen", "Didsbury Tennis Club",…
## $ locationtext                 <chr> "21 Assheton Road, Manchester", "509 Parr…
## $ postcode                     <chr> "M40 1UB", "M20 5GQ", "M4 1QB", "M22 9TF"…
## $ entertainmenttypeuri         <chr> "http://id.esd.org.uk/entertainment/6", N…
## $ entertainmenttypelabel       <chr> "Recorded Music", NA, "Live Music|Recorde…
## $ latenightrefreshment         <lgl> TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRU…
## $ alcoholsupply                <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,…
## $ openinghours                 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ statusuri                    <chr> "http://id.esd.org.uk/premisesLicenceStat…
## $ statuslabel                  <chr> "Current", "Current", "Current", "Current…
## $ licencestartdate             <chr> "05/04/2005", "23/04/2005", "22/04/2005",…
## $ licenceenddate               <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ onpremisesalcoholsale        <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ offpremisesalcoholsale       <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ licenceholder                <chr> "Mrs Rasmi Panchal", "Didsbury Lawn Tenni…
## $ licenceholderaddress         <chr> "23 Assheton Road Manchester", "509 Parrs…
## $ licenceholderpostcode        <chr> "M40 1UB", "M20 5GQ", "M4 1QB", "M22 9TF"…
## $ applicanttypeuri             <chr> "http://id.esd.org.uk/premisesLicenceAppl…
## $ applicanttypelabel           <chr> "Individual", NA, "Limited Company", NA, …
## $ designatedpremisessupervisor <chr> "Mr Mahesh C B Panchal", NA, "David Holli…
## $ supervisorlicenceno          <chr> "31726", NA, "1761", NA, "PL5031", "1859"…
## $ supervisoraddress            <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ supervisorpostcode           <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ conditions                   <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ decisiondate                 <chr> "05/04/2005", "23/04/2005", "22/04/2005",…
## $ decidedby                    <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ licenceurl                   <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ uprn                         <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ geopointlicensingurl         <chr> "http://www.nationalarchives.gov.uk/doc/o…

Since there are more than 65K entries here, to illustrate geocoding, we will slice the data to include only the top 50 entries, then extract the complete address to a new column, and finally, get the coordinates of the complete address.

lic_prem <- lic_prem |> 
  slice(1:50) |>  # Select first 50 entries
  mutate(complete_address = paste(locationtext, postcode, sep = ", ")) |> 
  geocode(complete_address, method = "osm")
## Passing 50 addresses to the Nominatim single address geocoder
## Query completed in: 63.6 seconds

Making sure that the coordinates are numeric:

glimpse(lic_prem)
## Rows: 50
## Columns: 39
## $ extractdate                  <chr> "10/10/2014", "10/10/2014", "10/10/2014",…
## $ organisationuri              <chr> "http://opendatacommunities.org/id/metrop…
## $ organisationlabel            <chr> "Manchester", "Manchester", "Manchester",…
## $ casereference                <dbl> 1565, 1823, 1824, 1826, 1834, 1841, 1854,…
## $ casedate                     <chr> "07/03/2005", "25/03/2005", "24/03/2005",…
## $ servicetypeuri               <chr> "http://id.esd.org.uk/service/860", "http…
## $ servicetypelabel             <chr> "Premises Licence", "Club Premises Certif…
## $ premisesname                 <chr> "Fresh & Frozen", "Didsbury Tennis Club",…
## $ locationtext                 <chr> "21 Assheton Road, Manchester", "509 Parr…
## $ postcode                     <chr> "M40 1UB", "M20 5GQ", "M4 1QB", "M22 9TF"…
## $ entertainmenttypeuri         <chr> "http://id.esd.org.uk/entertainment/6", N…
## $ entertainmenttypelabel       <chr> "Recorded Music", NA, "Live Music|Recorde…
## $ latenightrefreshment         <lgl> TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRU…
## $ alcoholsupply                <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,…
## $ openinghours                 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ statusuri                    <chr> "http://id.esd.org.uk/premisesLicenceStat…
## $ statuslabel                  <chr> "Current", "Current", "Current", "Current…
## $ licencestartdate             <chr> "05/04/2005", "23/04/2005", "22/04/2005",…
## $ licenceenddate               <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ onpremisesalcoholsale        <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ offpremisesalcoholsale       <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ licenceholder                <chr> "Mrs Rasmi Panchal", "Didsbury Lawn Tenni…
## $ licenceholderaddress         <chr> "23 Assheton Road Manchester", "509 Parrs…
## $ licenceholderpostcode        <chr> "M40 1UB", "M20 5GQ", "M4 1QB", "M22 9TF"…
## $ applicanttypeuri             <chr> "http://id.esd.org.uk/premisesLicenceAppl…
## $ applicanttypelabel           <chr> "Individual", NA, "Limited Company", NA, …
## $ designatedpremisessupervisor <chr> "Mr Mahesh C B Panchal", NA, "David Holli…
## $ supervisorlicenceno          <chr> "31726", NA, "1761", NA, "PL5031", "1859"…
## $ supervisoraddress            <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ supervisorpostcode           <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ conditions                   <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ decisiondate                 <chr> "05/04/2005", "23/04/2005", "22/04/2005",…
## $ decidedby                    <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ licenceurl                   <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ uprn                         <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ geopointlicensingurl         <chr> "http://www.nationalarchives.gov.uk/doc/o…
## $ complete_address             <chr> "21 Assheton Road, Manchester, M40 1UB", …
## $ lat                          <dbl> 53.49526, 53.40512, 53.48318, 53.38518, 5…
## $ long                         <dbl> -2.170846, -2.230231, -2.239146, -2.26143…

Creating leaflet map:

leaflet(data = lic_prem) |> 
  addTiles() |> 
  addMarkers(
    lng = ~long,
    lat = ~lat,
    popup = ~as.character(premisesname),
    label = ~as.character(premisesname)
  )
## Warning in validateCoords(lng, lat, funcName): Data contains 5 rows with either
## missing or invalid lat/lon values and will be ignored

Measuring distance more throughly

How far are police stations in Madrid?

Reading in data:

comisarias <- read_csv("data/data/nationalpolice.csv")
## Rows: 34 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): NOMBRE
## dbl (2): X, Y
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
comisarias_sf <- st_as_sf(
  comisarias,
  coords = c("X", "Y"),
  crs = 4326
)

Creating unique IDs for each row:

comisarias_sf$id <- as.numeric(rownames(comisarias_sf))

Get boundary data for Madrid

madrid <- st_read("data/data/madrid.geojson")
## Reading layer `madrid' from data source 
##   `/home/norman/Documents/ThirdBrain/x1_Projects/RProjects/Notes-on-Crime-Mapping-and-Spatial-Data-Analysis-in-R/data/data/madrid.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 1 feature and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -3.888963 ymin: 40.31206 xmax: -3.518126 ymax: 40.64328
## Geodetic CRS:  WGS 84

Plotting with leaflet:

leaflet(comisarias_sf) |> 
  addTiles() |> 
  addMarkers(data = comisarias_sf) |> 
  addPolygons(data = madrid)

Distance in geographical space

Common distances used in spatial data science: - Euclidean distance: the length of a segment connected by 2 points in a 2d space. - great circle distance: the length of arc linking 2 points on a sphere. - Manhattan distance: distance between points along a rectilinear path (grid-like)

Calculating distance between a selected police headquarter to two other headquarters:

dist_headquarters <- st_distance(
  slice(comisarias_sf, 34),
  slice(comisarias_sf, c(1, 10, 25))
)

dist_headquarters
## Units: [m]
##          [,1]     [,2]     [,3]
## [1,] 8124.085 5085.917 8554.864

Expressing the distance units in kilometers:

set_units(dist_headquarters, "km")
## Units: [km]
##          [,1]     [,2]     [,3]
## [1,] 8.124085 5.085917 8.554864

Calculating distances between all police stations:

m_distance <- st_distance(comisarias_sf)
head(m_distance)
## Units: [m]
##           [,1]      [,2]      [,3]     [,4]      [,5]      [,6]       [,7]
## [1,]     0.000  4365.495  5423.888 18592.24  2788.721  5841.085  6146.7843
## [2,]  4365.495     0.000  1325.770 14228.38  3622.821  1666.964  1937.1795
## [3,]  5423.888  1325.770     0.000 13302.89  4037.707  1830.498  1931.0537
## [4,] 18592.242 14228.381 13302.887     0.00 17237.398 12822.591 12514.8359
## [5,]  2788.721  3622.821  4037.707 17237.40     0.000  5281.130  5533.3175
## [6,]  5841.085  1666.964  1830.498 12822.59  5281.130     0.000   308.2584
##           [,8]      [,9]     [,10]     [,11]     [,12]     [,13]     [,14]
## [1,] 11695.630  7909.153 10553.122  6676.909 11358.779  7601.352 11185.307
## [2,]  7833.044  3723.656  6193.266  2511.152  7700.904  3939.523  8819.637
## [3,]  7632.592  3413.614  5353.904  1257.578  7655.604  2623.228  9365.686
## [4,]  8729.769 10882.031  8041.864 12133.558  9602.549 12040.188 13447.852
## [5,] 11446.352  7281.888  9376.676  5115.122 11322.760  5486.120 12117.125
## [6,]  6167.415  2086.962  4797.362  2248.173  6058.148  4002.974  7535.317
##          [,15]     [,16]      [,17]     [,18]     [,19]     [,20]     [,21]
## [1,] 13550.684  1435.214  5782.0229  8124.881 10810.179  8986.842  8803.567
## [2,]  9376.275  4276.341  2037.9385  3811.016  6940.378  5319.830  5180.338
## [3,]  8843.792  5052.633  2561.8204  2729.465  5626.755  3995.157  3858.226
## [4,]  6142.660 18355.518 13107.9539 10586.518  9616.043 11189.868 11384.500
## [5,] 12856.793  1540.920  5613.5210  6670.043  8644.227  6765.962  6566.732
## [6,]  7752.663  5910.732   808.9659  2894.029  6486.607  5189.104  5104.604
##          [,22]     [,23]    [,24]     [,25]     [,26]     [,27]     [,28]
## [1,]  6574.161  6569.241 9039.032 13511.134  7332.848  9895.030 10018.527
## [2,]  2249.998  2247.377 4675.541  9191.243  3123.997  6450.696  6559.360
## [3,]  1255.085  1245.387 3842.079  8096.464  2849.886  6598.999  6692.794
## [4,] 12073.004 12080.153 9553.251  5563.385 11392.637 10882.416 10788.886
## [5,]  5290.620  5280.306 7874.576 11865.711  6683.999 10044.279 10156.276
## [6,]  1621.216  1630.395 3338.344  8041.725  1497.011  4871.694  4974.000
##          [,29]     [,30]     [,31]      [,32]     [,33]     [,34]
## [1,]  7407.900  5156.917  8381.809  6128.7114 18669.925  8124.085
## [2,]  6169.387  3328.854  5375.511  1768.4818 14307.231  4871.027
## [3,]  5421.308  2788.928  4150.850  1304.2686 13391.058  5242.508
## [4,] 15915.314 15100.234 12763.324 12463.5578   158.655 12120.650
## [5,]  4619.410  2589.821  5873.595  5180.9705 17333.146  8398.137
## [6,]  7251.805  4573.020  5740.168   814.0143 12892.244  3424.062

A practical example to evaluate distance

Checking the CRS used in madrid data:

st_crs(madrid)
## Coordinate Reference System:
##   User input: WGS 84 
##   wkt:
## GEOGCRS["WGS 84",
##     DATUM["World Geodetic System 1984",
##         ELLIPSOID["WGS 84",6378137,298.257223563,
##             LENGTHUNIT["metre",1]]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433]],
##     CS[ellipsoidal,2],
##         AXIS["geodetic latitude (Lat)",north,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433]],
##         AXIS["geodetic longitude (Lon)",east,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433]],
##     ID["EPSG",4326]]

Reprojecting the CRS of madrid to another using crsuggest (if we don’t know the EPSG code):

suggested_crs <- suggest_crs(madrid)
head(suggested_crs)
## # A tibble: 6 × 6
##   crs_code crs_name                         crs_type crs_gcs crs_units crs_proj4
##   <chr>    <chr>                            <chr>      <dbl> <chr>     <chr>    
## 1 2062     Madrid 1870 (Madrid) / Spain LCC project…    4903 m         +proj=lc…
## 2 3042     ETRS89 / UTM zone 30N (N-E)      project…    4258 m         +proj=ut…
## 3 25830    ETRS89 / UTM zone 30N            project…    4258 m         +proj=ut…
## 4 23030    ED50 / UTM zone 30N              project…    4230 m         +proj=ut…
## 5 32630    WGS 84 / UTM zone 30N            project…    4326 m         +proj=ut…
## 6 32430    WGS 72BE / UTM zone 30N          project…    4324 m         +proj=ut…

Transforming the CRS of madrid to the “best” suggestion from the crsuggest package:

madrid_meters <- st_transform(madrid, crs = 2062)
head(madrid_meters)
## Simple feature collection with 1 feature and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 582948.6 ymin: 634613.4 xmax: 614351.6 ymax: 671346.7
## Projected CRS: Madrid 1870 (Madrid) / Spain LCC
##   OBJECTID Shape_Leng Shape_Area     TM                       geometry
## 1        1   174177.9  604455107 Madrid MULTIPOLYGON (((603625.2 67...

Dividing Madrid into a 250m x 250m grid:

madrid_grid <- st_make_grid(madrid_meters, cellsize = 250)

Extracting only the points in the limits of Madrid:

madrid_grid <- st_intersection(madrid_grid, madrid_meters)

Plotting:

plot(madrid_grid)

Estimating the minimum distance value from the center of each grid, to the nearest station:

comisarias_sf_meters <- st_transform(comisarias_sf, crs = 2062)
distances <- st_distance(
  comisarias_sf_meters,
  st_centroid(madrid_grid)
) |> 
  as_tibble()

head(distances)
## # A tibble: 6 × 10,082
##       V1     V2     V3     V4     V5     V6     V7     V8     V9    V10    V11
##      [m]    [m]    [m]    [m]    [m]    [m]    [m]    [m]    [m]    [m]    [m]
## 1 16047. 16238. 16463. 16688. 16905. 17112. 17322. 17532. 17738. 17942. 18146.
## 2 14159. 14319. 14509. 14700. 14884. 15051. 15223. 15396. 15565. 15732. 15901.
## 3 13031. 13183. 13365. 13548. 13724. 13883. 14047. 14212. 14375. 14534. 14696.
## 4 17076. 17058. 17042. 17031. 17014. 16970. 16932. 16895. 16859. 16818. 16780.
## 5 13259. 13449. 13674. 13898. 14116. 14322. 14532. 14743. 14950. 15154. 15360.
## 6 14667. 14811. 14981. 15154. 15320. 15467. 15618. 15771. 15922. 16069. 16218.
## # ℹ 10,071 more variables: V12 [m], V13 [m], V14 [m], V15 [m], V16 [m],
## #   V17 [m], V18 [m], V19 [m], V20 [m], V21 [m], V22 [m], V23 [m], V24 [m],
## #   V25 [m], V26 [m], V27 [m], V28 [m], V29 [m], V30 [m], V31 [m], V32 [m],
## #   V33 [m], V34 [m], V35 [m], V36 [m], V37 [m], V38 [m], V39 [m], V40 [m],
## #   V41 [m], V42 [m], V43 [m], V44 [m], V45 [m], V46 [m], V47 [m], V48 [m],
## #   V49 [m], V50 [m], V51 [m], V52 [m], V53 [m], V54 [m], V55 [m], V56 [m],
## #   V57 [m], V58 [m], V59 [m], V60 [m], V61 [m], V62 [m], V63 [m], V64 [m], …

Processing our data in preparation for mapping in leaflet:

police_distances <- data.frame(
  us = st_transform(madrid_grid, crs = 4326), # set grid to WGS 84 CRS
  distance_km = map_dbl(distances, min) / 1000, # extract min. distance for each grid
  location_id = map_dbl(distances, function(x) match(min(x), x))
) |> # extract the value's index
  left_join(comisarias_sf, by = c("location_id" = "id"))

head(police_distances)
##                       geometry.x distance_km location_id
## 1 POLYGON ((-3.60848 40.31433...    8.639067          29
## 2 POLYGON ((-3.60848 40.31433...    8.829202          29
## 3 POLYGON ((-3.605535 40.3143...    9.053304          29
## 4 POLYGON ((-3.602591 40.3143...    9.277918          29
## 5 POLYGON ((-3.599646 40.3143...    9.495928          29
## 6 POLYGON ((-3.596702 40.3143...    9.703742          29
##                                                                    NOMBRE
## 1 Madrid - Usera - Villaverde 1. Comisaría tramitación de DNI y pasaporte
## 2 Madrid - Usera - Villaverde 1. Comisaría tramitación de DNI y pasaporte
## 3 Madrid - Usera - Villaverde 1. Comisaría tramitación de DNI y pasaporte
## 4 Madrid - Usera - Villaverde 1. Comisaría tramitación de DNI y pasaporte
## 5 Madrid - Usera - Villaverde 1. Comisaría tramitación de DNI y pasaporte
## 6 Madrid - Usera - Villaverde 1. Comisaría tramitación de DNI y pasaporte
##                   geometry.y
## 1 POINT (-3.693897 40.35755)
## 2 POINT (-3.693897 40.35755)
## 3 POINT (-3.693897 40.35755)
## 4 POINT (-3.693897 40.35755)
## 5 POINT (-3.693897 40.35755)
## 6 POINT (-3.693897 40.35755)

Inspect the distribution of the calculated distances:

hist(police_distances$distance_km, main = "Distance to nearest police station")

More preparation for mapping: creating a custom icon for plotting data points…

icon_url_pt1 <- "https://upload.wikimedia.org/wikipedia/commons/"
icon_url_pt2 <- "a/ad/189-woman-police-officer-1.svg"

# creating the icon
police_icon <- makeIcon(
  paste0(icon_url_pt1, icon_url_pt2), 
  iconWidth = 12,
  iconHeight = 20
)

Creating a color scale for plotting:

bins <- quantile(police_distances$distance_km)

pal <- colorBin(
  c("#0868AC", "#43A2CA", "#7BCCC4", "#BAE4BC", "#F0F9E8"),
  domain = police_distances$distance_km,
  bins = bins,
  reverse = TRUE
)

Finally creating the leaflet map:

full_map <- leaflet() |> 
  addTiles() |> 
  addMarkers(
    data = comisarias_sf,
    icon = ~police_icon,
    group = "Police stations"
  ) |> 
  addPolygons(
    data = police_distances[[1]],
    fillColor = pal(police_distances$distance_km),
    fillOpacity = 0.8,
    weight = 0,
    opacity = 1,
    color = "transparent",
    group = "Distances",
    highlight = highlightOptions(
      weight = 2, color = "#666",
      bringToFront = TRUE, opacity = 1
    ),
    popupOptions = popupOptions(
      autoPan = FALSE,
      closeOnClick = TRUE,
      textOnly = TRUE
    )
  ) |> 
  addLegend(
    pal = pal,
    values = police_distances$distance_km,
    opacity = 0.8,
    title = "Distance (Km)",
    position = "bottomright"
  ) |> 
  addScaleBar(position = "bottomleft")

full_map